<?php
/****
模型类的父类，包含了每个子类都有的操作
****/
defined('JSJZJX')||exit('非法访问！');
class Model {
    protected $table = NULL; // 是model所控制的表
    protected $db = NULL; // 是引入的mysql对象
    protected $pk='';//定义要操作的表的主键

    protected $fields=array();//表中字段数组，在Model的子类中可以desc分析出或手动写出
   /****
   表中的字段减掉cut后的POST上来的数组,剩下的字段，需要字段填充
   一般在Model的子类中手动写好
   ****/
    protected $leftfields=array();//需要补充的字段的数组
    
    protected $rules=array();//表单字段的验证规则，要到子类中写出。二维的
    protected $error = array();
    /****
    每当自动创建一个Model类的实例时，就应当建立一个mydb对象
	mydb对象才能 执行autoExecute等数据库操作方法，记住：对数据库的
	操作务必在Model中
	****/
	public function __construct(){
		$this->db=mydb::getIns();
	}
	/****
	并非一个表就一定要一个Model,下面的方法将Model变成通用Model
	$bable可以任意赋值了
	****/
    public function table($table) {
        $this->table = $table;
    }
  /*  /****
    格式 $this->valid=array(
        array('验证的字段名'，0、1、2（验证场景），'报错提示'，
        'require/in(某几种情况)/between(范围)/length(某个范围)')
        );
    例子：
        array('goods_name',1,'商品名不能为空','required'),
        array('cat_id',1,'栏目id必须是整形值'，'number'),
        array('is_new',0,'is_new 只能是0或1'，'in','0,1'),
        array('goods_breif',2,'商品简介在10-100个字符','length','10,100')
    ****/

   
    public function  validate($data) {
        if(empty($this->rules)) {//没有规则，就不用验证了
            return true;
        }

        $this->error = array();

        foreach($this->rules as $k=>$v) {
            //print_r($v);
            switch($v[1]) {
                case 1:
                    if(!isset($data[$v[0]])) {
                        $this->error[] = $v[2];
                        return false;
                    }
                    
                    if(!isset($v[4])) {
                        $v[4] = '';
                    }

                    if(!$this->check($data[$v[0]],$v[3],$v[4])) {
                        $this->error[] = $v[2];
                        
                        return false;
                    }
                    break;
                case 0:
                    if(isset($data[$v[0]])) {

                        if(!$this->check($data[$v[0]],$v[3],$v[4])) {
                            $this->error[] = $v[2];
                            
                            return false;
                        }
                    }
                    break;
                case 2:
                    if(isset($data[$v[0]]) && !empty($data[$v[0]])) {
                        if(!$this->check($data[$v[0]],$v[3],$v[4])) {
                            $this->error[] = $v[2];
                            
                            return false;
                        }
                    }
            }
        }

        return true;

    }

    public function getErr(){
        return $this->error;
        
    }

    protected function check($value,$rule='',$parm='') {
        switch($rule) {
            case 'require':
                return !empty($value);
               

            case 'number':
                return is_numeric($value);
               
            case 'in':
                $tmp = explode(',',$parm);
                return in_array($value,$tmp);
               
            case 'between':
                list($min,$max) = explode(',',$parm);
                return $value >= $min && $value <= $max;
                
            case 'length':

                list($min,$max) = explode(',',$parm);
                return strlen($value) >= $min && strlen($value) <= $max;
                
            case 'email':
                // 判断$value是否是email,可以用正则表达式,但现在没学.
                // 因此,此处用系统函数来判断
                return (filter_var($value,FILTER_VALIDATE_EMAIL) !== false);
                
            default:
                return false;
               
        }
    }
    /****
    接收POST上来的表单数据形成的数组，然后进行切除，只留下与表中字段对应的单元，
    为向表中插入数据做好准备
    ****/
    public function cut($array=array()){
    	$data=array();
    	foreach($array as $k=>$v){
    		if(in_array($k,$this->fields)){
    			$data[$k]=$v;
    		}
    	}
    	return $data;

    }
    /****
    表中有字段，但$POST传上来的又没有，则自动给这样的字段赋值
    一般是接收cut()函数处理后的返回值，返回值送到数据表
    ****/
    public function fillFields($data){

    	foreach ($this->leftfields as $k => $v) {
    		if(!array_key_exists($v[0], $data)){
    		switch ($v[1]) {
    			case 'value':
    				$data[$v[0]]=$v[2];
    				break;
    			case 'function':
    				$data[$v[0]]=call_user_func($v[2]);
    					break;
    			
    			default:
    				break;
    		}
    		
    	}
    }
    return $data;//应该插入到表的数据

 }
    /****
    最基本的增删改查，都用，所以写在父类里
    ****/

    //$data要插入的数据，键是表的字段，执行成功返回true
    public function add($data){
        
    	return $this->db->autoExec($this->table,$data);
    }

    //$id--主键，返回影响的行数
    public function delete($id){

    	$sql='delete from '.$this->table.' where '.$this->pk.'='.$id;
    	if($this->db->query($sql)){
    		return $this->db->affected_rows();
    	}else{
    		return false;
    	}
    }

    //$id--主键，返回影响的行数,$data 更新数据的数组
    public function update($data,$id){
    	$res=$this->db->autoExec($this->table,$data,'update',' where '.$this->pk.'='.$id);
    	if($res){
    		return $this->db->affected_rows();
    	}else{
    		return false;
    	}
    }

    //查询所有数据，返回数据数组
    public function findAll(){
    	$sql='select * from '.$this->table;
    	return $this->db->getAll($sql);
    }
    
    //$id--主键，查一行数据
    public function findOne($id){
    	$sql='select * from '.$this->table.' where '.$this->pk.'='.$id;
    	return $this->db->getRow($sql);

    }

    //查询每页所用的数据
    public function findPerPage($offset=0,$limit=5){

        $sql='select * from '.$this->table.' limit '.$offset.','.$limit;
        return $this->db->getAll($sql);
    }


//获取分类$id的子孙树,将getAll()获得的结果格式化
    public function getCategoryTree($arr,$aid=0,$lev=0){//
        $tree=array();
        foreach ($arr as $v) {
            if($v['pid']==$aid){
            $v['lev']=$lev;
            $tree[]=$v;
            $tree=array_merge($tree,$this->getCategoryTree($arr,$v['id'],$lev+1));
            
    }
}
        return $tree;
}

/*public function addAll($datas){//一次插入多条数据

    //$datas=array(array(a,b,2),array(f,2,t),array('aaaa','string',6,));
    //if(!is_array($datas[0])) return false;
    //$fields = array_keys($datas[0]);
    //array_walk($fields, array($this, 'parseKey'));
        $values  =  array();
        foreach ($datas as $data){
            $value   =  array();
            foreach ($data as $key=>$val){
                //$val   =  $this->parseValue($val);
               // if(is_scalar($val)) { // 过滤非标量数据
                    $value[]   =  $val;

            }
            $values[]    = '('.implode(',', $value).')';
           }
        $sql   = 'INSERT INTO '.$this->table.'(role_id,node_id,level) VALUES '.implode(',',$values);
       return $this->db->query($sql);

}*/
    public function addAll($datas){//一次插入多条数据
        $values  =  array();
        $fields = array();
        foreach ($datas as $data){
            $fields = implode(',',array_keys($data));
            $value   =  array();
            foreach ($data as $key=>$val){
                $value[]   =  "'".$val."'";
            }
            $values[]    = '('.implode(',', $value).')';
           }
        $sql   = 'INSERT INTO '.$this->table.'('.$fields.') VALUES '.implode(',',$values);
       return $this->db->query($sql);

    }
public function insertId(){
    return $this->db->insert_id();

  }


  
}


?>

    